package com.zg.system.auth;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zg.common.core.R;
import com.zg.common.core.dao.auth.*;
import com.zg.system.auth.domain.req.*;
import com.zg.system.auth.domain.vo.RoleMenuVo;
import com.zg.system.auth.domain.vo.RoleUserVo;
import com.zg.system.auth.domain.vo.RoleVo;
import com.zg.system.auth.service.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;

@Api(tags = {"角色管理"})
@RestController
@RequiredArgsConstructor
public class RoleController {
    private final AuthRoleDao roleDao;
    private final AuthRoleMenuDao roleMenuDao;
    private final AuthRoleUserDao roleUserDao;
    private final RoleService roleService;

    @ApiOperation("新增角色")
    @PostMapping("/role/add")
    public R<Void> add(@RequestBody @Valid RoleAddReq req) {
        boolean nameExits = roleDao.exists(
                new LambdaQueryWrapper<AuthRole>()
                        .eq(AuthRole::getName, req.getName())
        );
        if (nameExits) {
            return R.error("角色名称已存在");
        }
        boolean codeExits = roleDao.exists(
                new LambdaQueryWrapper<AuthRole>()
                        .eq(AuthRole::getCode, req.getCode())
        );
        if (codeExits) {
            return R.error("角色编码已存在");
        }
        AuthRole authRole = BeanUtil.copyProperties(req, AuthRole.class);
        authRole.setSearchStr(authRole.getName() + authRole.getCode());
        roleDao.save(authRole);
        return R.success();
    }

    @ApiOperation("修改角色")
    @PostMapping("/role/edit")
    public R<Void> edit(@RequestBody @Valid RoleEditReq req) {
        AuthRole authRole = roleDao.getById(req.getRoleId());
        if (authRole == null) {
            return R.error("请选择正确的角色");
        }
        if (!authRole.getName().equals(req.getName())) {
            boolean nameExits = roleDao.exists(
                    new LambdaQueryWrapper<AuthRole>()
                            .eq(AuthRole::getName, req.getName())
            );
            if (nameExits) {
                return R.error("角色名称已存在");
            }
            authRole.setName(req.getName());
        }
        if (!authRole.getCode().equals(req.getCode())) {
            boolean codeExits = roleDao.exists(
                    new LambdaQueryWrapper<AuthRole>()
                            .eq(AuthRole::getCode, req.getCode())
            );
            if (codeExits) {
                return R.error("角色编码已存在");
            }
            authRole.setCode(req.getCode());
        }
        authRole.setSearchStr(authRole.getName() + authRole.getCode());
        roleDao.updateById(authRole);
        return R.success();
    }

    @ApiOperation("删除角色")
    @ApiImplicitParam(name = "idList", value = "角色id数组", required = true)
    @PostMapping("/role/remove")
    public R<Void> remove(@RequestBody List<Long> idList) {
        roleService.remove(idList);
        return R.success();
    }

    @ApiOperation("分页查询角色")
    @PostMapping("/role/page")
    public R<IPage<RoleVo>> page(@RequestBody @Valid RolePageReq req) {
        IPage<AuthRole> pageParam = new Page<>(req.getPage(), req.getPageSize());
        LambdaQueryWrapper<AuthRole> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(req.getSearchStr())) {
            queryWrapper.like(AuthRole::getSearchStr, "%" + req.getSearchStr() + "%");
        }
        IPage<AuthRole> page = roleDao.page(pageParam, queryWrapper);
        IPage<RoleVo> result = new Page<>();
        BeanUtil.copyProperties(page, result);
        return R.success(result);
    }

    @ApiOperation("角色分配菜单")
    @PostMapping("/role/addMenu")
    public R<Void> addMenu(@RequestBody @Valid RoleAddMenuReq param) {
        roleService.addMenu(param);
        return R.success();
    }

    @ApiOperation("查询角色下的菜单")
    @PostMapping("/role/listMenu")
    public R<List<RoleMenuVo>> listMenu(@RequestBody @Valid RoleListMenuReq param) {
        List<AuthRoleMenu> list = roleMenuDao.list(
                new LambdaQueryWrapper<AuthRoleMenu>()
                        .eq(AuthRoleMenu::getRoleId, param.getRoleId())
        );
        return R.success(BeanUtil.copyToList(list, RoleMenuVo.class));
    }

    @ApiOperation("角色分配用户")
    @PostMapping("/role/addUser")
    public R<Void> addUser(@RequestBody @Valid RoleAddUserReq param) {
        roleService.addUser(param);
        return R.success();
    }

    @ApiOperation("查询角色下的用户")
    @PostMapping("/role/listUser")
    public R<List<RoleUserVo>> listUser(@RequestBody @Valid RoleListUserReq param) {
        List<AuthRoleUser> list = roleUserDao.list(
                new LambdaQueryWrapper<AuthRoleUser>()
                        .eq(AuthRoleUser::getRoleId, param.getRoleId())
        );
        return R.success(BeanUtil.copyToList(list, RoleUserVo.class));
    }
}
